package com.example.javaproject.thread.thread;

/**
 * Description:  如何关闭线程
 * <br/>Author:  tianjinyong
 * <br/>Date:    2020/7/6 4:36 PM
 *
 * @see <a href="https://baijiahao.baidu.com/s?id=1662278131416406934&wfr=spider&for=pc">优雅的停止线程,一般选择标志位，特殊情况下选择interrupt</>
 */
public class T_02_HowToStopThread {
    private volatile static boolean flag = true;

    public static void main(String[] args) {
//        testStopThreadByTag();
//        testNotStopThreadByTag();
        testStopThreadByInterrupt();
    }

    /**
     * 一般情况下 这样可以做到停止线程，但是当线程运行过程中处于阻塞状态时，利用标志位当方法无法停止线程当
     */
    private static void testStopThreadByTag() {
        new Thread(() -> {
            try {
                while (flag) { // 判断标志标位
                    System.out.println("运行中");
                }
                System.out.println("程序运行结束");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();

        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        flag = false;

    }

    /**
     * 演示 标志位不能正确停止线程(线程处于wait状态), 不会输出"程序运行结束"
     */
    public static void testNotStopThreadByTag() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    while (flag) { // 判断标志标位
                        System.out.println("运行中");
                        synchronized (this) {
                            wait();
                        }
                    }
                    System.out.println("程序运行结束");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();

        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        flag = false;
    }

    /**
     * 通过interrupt方法停止线程
     */
    public static void testStopThreadByInterrupt() {
        Thread thread  = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    while (flag) { // 判断标志标位
                        System.out.println("运行中");
                        synchronized (this) {
                            wait();
                        }
                    }
                    System.out.println("程序运行结束");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    System.out.println("程序运行结束");
                }
            }
        });

        thread.start();

        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        flag = false;
        thread.interrupt();
    }


}
